package com.ruoyi.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.CertUtil;
import com.ruoyi.common.WxValueConfig;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.app.*;
import com.ruoyi.system.mapper.CommunityMemberMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.UserMapper;
import com.ruoyi.system.mapper.app.*;
import com.ruoyi.system.service.OrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderCardChargeMapper orderCardChargeMapper;
    @Autowired
    OrderChargeMapper orderChargeMapper;
    @Autowired
    OrderComboMapper orderComboMapper;
    @Autowired
    RechargeOrderMapper rechargeOrderMapper;
    @Autowired
    ParticipationMapper participationMapper;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    WxValueConfig wxValueConfig;

    @Autowired
    UserMapper userMapper;

    @Autowired
    CommunityMemberMapper communityMemberMapper;

    @Autowired
    CardMapper cardMapper;

    @Override
    public void operatorDivide() {
        List<Participation> participations = participationMapper.getNotDivide();
        for (Participation participation : participations) {
            if (participation.getParticipationTime().getTime() < System.currentTimeMillis()) {
                SysUser sysUser = sysUserMapper.selectUserById(participation.getSysId());
                sysUser.setWithdrawBalance(sysUser.getWithdrawBalance().add(participation.getMoney()));
                participation.setParticipationState(1);
                sysUserMapper.updateUser(sysUser);
                participationMapper.updateByPrimaryKeySelective(participation);
            }
        }
    }

    @DataScope(deptAlias = "d", userAlias = "u")
    @Override
    public List<Order> chargeOrderList(Order order,String startTime ,String endTime) {
        return orderMapper.chargeOrderList(order,startTime,endTime);
    }

    @Override
    public AjaxResult orderInfo(Long orderId, Integer type) {
        if (type == 1) {
            return AjaxResult.success(orderChargeMapper.selectByPrimaryKey(orderId));
        } else if (type == 2) {
            return AjaxResult.success(orderComboMapper.selectByPrimaryKey(orderId));
        } else if (type == 3) {
            return AjaxResult.success(orderCardChargeMapper.selectByPrimaryKey(orderId));
        }else if(type == 4){
            Order order = orderMapper.selectByPrimaryKey(orderId);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("afterMoney",order.getMoney());
            jsonObject.put("beforeMoney",0);
            jsonObject.put("chargeMoney",order.getMoney());
            jsonObject.put("chargeTime",order.getCreateTime());
            jsonObject.put("discountMoney",0);
            jsonObject.put("orderId",order.getId());
            return AjaxResult.success(jsonObject);
        }
        return null;
    }

    @DataScope(deptAlias = "d", userAlias = "u")
    @Override
    public List<RechargeOrder> rechargeList(RechargeOrder rechargeOrder,String startTime ,String endTime) {
        return rechargeOrderMapper.rechargeListAdmin(rechargeOrder,startTime,endTime);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void orderRefund(Long orderId, BigDecimal refundMoney) {
        Order order = orderMapper.selectByPrimaryKey(orderId);
        CommunityMember communityMember = communityMemberMapper.selectByUser(order.getUserId(),order.getCommunityId());
        SysUser sysUser = sysUserMapper.selectUserById(order.getOperatorId());
        OrderCharge orderCharge = orderChargeMapper.selectByPrimaryKey(order.getId());


        if (sysUser == null) {
            throw new ServiceException("运营商不存在");
        }
        if (sysUser.getWithdrawBalance().doubleValue() < refundMoney.doubleValue() || sysUser.getBalance().doubleValue() < refundMoney.doubleValue()) {
            throw new ServiceException("运营商余额不足，退款失败！");
        }
        if (order.getType() != 1) {
            throw new ServiceException("订单类型错误！");
        }
        if (order.getOrderState() != 1) {
            throw new ServiceException("订单无法退款！");
        }
        if (refundMoney.doubleValue() > order.getMoney().doubleValue()) {
            throw new ServiceException("退款金额错误！");
        }


        //金额
        if (order.getOrderType() == 1) {
            if (communityMember.getBalance().doubleValue() < refundMoney.doubleValue()) {
                throw new ServiceException("退款金额大于余额剩余金额");
            }

            communityMember.setBalance(communityMember.getBalance().subtract(refundMoney));
            communityMember.setDiscountBalance(communityMember.getDiscountBalance().subtract(orderCharge.getDiscountMoney()));
        }        //包月
        else if (order.getOrderType() == 2) {
            communityMember.setIsBy(0);
            communityMember.setByTime(null);
        }
        //电卡
        else if (order.getOrderType() == 3) {
            Card card = cardMapper.selectByNum(orderCardChargeMapper.selectByPrimaryKey(orderId).getCardNum());
            if (card.getMoney().doubleValue() < refundMoney.doubleValue()) {
                throw new ServiceException("退款金额大于余额剩余金额");
            }
            card.setMoney(card.getMoney().subtract(refundMoney));
            cardMapper.updateByPrimaryKeySelective(card);
        }

        sysUser.setBalance(sysUser.getBalance().subtract(refundMoney));
        sysUser.setWithdrawBalance(sysUser.getWithdrawBalance().subtract(refundMoney));

        wxRefund(order.getOrderNo(),refundMoney,order.getMoney());

        //添加到记录
        Participation participation = new Participation();
        participation.setParticipationState(2);
        participation.setSysId(order.getOperatorId());
        participation.setOrderNum(order.getOrderNo());
        participation.setOrderId(orderId);
        participation.setType(4);
        participation.setMoney(refundMoney.negate());
        participation.setCreateTime(new Date());
        participation.setParticipationState(1);
        participation.setParticipationTime(new Date());

        participation.setRemark("用户退款:退款金额：" + refundMoney + "元。" );
        Order order1 = new Order();
        order1.setId(order.getId());

        if(order.getMoney().doubleValue()== refundMoney.doubleValue()){
            order1.setIsRefund("2");
        }else {
            order1.setIsRefund("1");
        }
        orderMapper.updateByPrimaryKeySelective(order1);
        participationMapper.insertSelective(participation);
        sysUserMapper.updateUser(sysUser);
        communityMemberMapper.updateByPrimaryKey(communityMember);


    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<Order> chargeOrderCountList(Order order,String startTime, String endTime) {
        return orderMapper.chargeOrderCountList(order,startTime, endTime);
    }

    /**
     *
     * @param orderNum 订单号
     * @param refundMoney 退款金额
     * @param orderMoney 订单总金额
     * @throws Exception
     */
    @SneakyThrows
    public void wxRefund(String orderNum,BigDecimal refundMoney,BigDecimal orderMoney)  {



        log.info(new BigDecimal(String.valueOf(orderMoney.doubleValue()*100)).setScale(2,BigDecimal.ROUND_HALF_UP).toString());
        BigDecimal totalFee = new BigDecimal(String.valueOf(orderMoney.doubleValue()*100)).setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal refundFee = new BigDecimal(String.valueOf(refundMoney.doubleValue()*100)).setScale(2,BigDecimal.ROUND_HALF_UP);
        Map param = new HashMap();
        param.put("appid", wxValueConfig.getAPPID());//公众账号ID
        param.put("mch_id", wxValueConfig.getMCH_ID());//商户
        param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
        param.put("out_trade_no", orderNum);//交易订单号
        param.put("out_refund_no", WXPayUtil.generateNonceStr().substring(0, 18));
        param.put("total_fee", totalFee.stripTrailingZeros().toPlainString() );//金额（分）
        param.put("refund_fee",refundFee.stripTrailingZeros().toPlainString() );

        String xmlParam = WXPayUtil.generateSignedXml(param, wxValueConfig.getKEY());
        String xmlResult = CertUtil.HttpsPost("https://api.mch.weixin.qq.com/secapi/pay/refund", xmlParam);
        Map map = WXPayUtil.xmlToMap(xmlResult);

        System.out.println("返回参数:" + xmlResult);
        log.info(xmlParam);

        if ("SUCCESS".equals(map.get("return_code")) && map.get("err_code") == null) {
            log.info("微信退款订单:【{}】{}", orderNum, "退款成功");

        } else {

            log.info(param.toString());
            log.info(map.toString());
            log.info("微信退款订单:【{}】{}", orderNum, "退款失败");
            throw new ServiceException(map.get("err_code_des").toString());
        }

    }



}
